package org.xmap.ui.control;
import java.util.Vector;
import org.xmap.app.Env;
import org.xmap.ui.base.Rect;
/**
 * <p>菜单类是菜单项的容器类，每个菜单对象下面可以有多个菜单项对象，每个菜单项对象又有一个菜单对象，这样形成一个树状的菜单结构。</p>
 * <p>菜单对象没有名字，只有菜单项对象才有名字，用于显示和菜单响应。菜单项对象还保存是否展开其子菜单的状态。</p>
 * @author Zealot
 * @version 1.0
 */
public final class Menu {
    /**
     * 更多子菜单的图标的宽度。
     */
    private static int moreIconWidth = 0;
    /**
     * 默认菜单的宽度。
     */
    private static int defaultMenuWidth = 60;
    /**
     * 设置更多子菜单的图标的宽度。
     * @param moreIconWidth int 更多子菜单的图标的宽度。
     */
    public static void setMoreIconWidth(int moreIconWidth) {
        Menu.moreIconWidth = moreIconWidth;
    }
    /**
     * 设置菜单的默认宽度。
     * @param defaultMenuWidth int 菜单的默认宽度。
     */
    public static void setDefaultMenuWidth(int defaultMenuWidth) {
        Menu.defaultMenuWidth = defaultMenuWidth;
    }
    /**
     * 当前菜单覆盖的区域。
     */
    private Rect r;
    /**
     * 当前菜单的菜单项。
     */
    private Vector items;
    /**
     * 当前选中的菜单项序号。
     */
    private int selectIndex;
    /**
     * 当前菜单组中，最长的菜单宽度。
     */
    private int maxTextWidth;
    /**
     * 默认构造函数。
     */
    public Menu() {
        this.r = new Rect();
        this.items = new Vector();
        this.selectIndex = -1;
        this.maxTextWidth = Menu.moreIconWidth + Menu.defaultMenuWidth;
    }
    /**
     * 获得当前菜单覆盖的区域。
     * @return Rect 覆盖的区域。
     */
    public Rect getRect() {
        return this.r;
    }
    /**
     * 添加指定文字的菜单项。
     * @param text String 指定文字。
     */
    public void addMenuItem(String text) {
        if (this.selectIndex == -1) {
            this.selectIndex = 0;
        }
        boolean add = true;
        for (int i = 0; i < this.items.size(); i++) {
            MenuItem mi = (MenuItem)this.items.elementAt(i);
            if (mi.getText().equals(text)) {
                add = false;
            }
        }
        if (add) {
            MenuItem mi = new MenuItem(text);
            this.items.addElement(mi);
            this.calculateWidth();
        }
    }
    /**
     * 添加指定文字和子菜单的菜单项。
     * @param text String 指定文字。
     * @param m Menu 指定子菜单。
     */
    public void addMenuItem(String text, Menu m) {
        if (this.selectIndex == -1) {
            this.selectIndex = 0;
        }
        MenuItem mi = new MenuItem(text, m);
        this.items.addElement(mi);
        this.calculateWidth();
    }
    /**
     * 修改指定字符串的菜单项。
     * @param from String 修改前的菜单项文字。
     * @param to String 修改后的菜单项文字。
     */
    public void changeMenuItem(String from, String to) {
        if (from != null && to != null && !from.equals(to)) {
            for (int i = 0; i < this.items.size(); i++) {
                MenuItem mi = (MenuItem)this.items.elementAt(i);
                if (mi.getText().equals(from)) {
                    mi.setText(to);
                }
                if (mi.hasSubmenu()) {
                    mi.getSubmenu().changeMenuItem(from, to);
                }
            }
            this.calculateWidth();
        }
    }
    /**
     * 移除指定字符串的菜单项。
     * @param text String 指定字符串。
     * @return boolean 是否移除成功。
     */
    public boolean removeMenuItem(String text) {
        boolean result = false;
        for (int i = 0; i < this.items.size(); i++) {
            MenuItem mi = (MenuItem)this.items.elementAt(i);
            if (mi.getText().equals(text)) {
                this.items.removeElementAt(i);
                i--;
                result = true;
            }
        }
        if (result) {
            if (this.selectIndex >= this.items.size()) {
                this.selectIndex = this.items.size() - 1;
            }
            this.calculateWidth();
        }
        return result;
    }
    /**
     * 通过指定序号来获得菜单项。
     * @param index int 指定序号。
     * @return MenuItem 菜单项。
     */
    public MenuItem getItemByIndex(int index) {
        if (index >= 0 && index < this.items.size()) {
            return (MenuItem)this.items.elementAt(index);
        } else {
            return null;
        }
    }
    /**
     * 通过指定字符串来获得菜单项。
     * @param text String 指定字符串。
     * @return MenuItem 菜单项。
     */
    public MenuItem getItemByString(String text) {
        for (int i = 0; i < this.items.size(); i++) {
            MenuItem mi = (MenuItem)this.items.elementAt(i);
            if (mi.getText().equals(text)) {
                return mi;
            }
        }
        return null;
    }
    /**
     * 获得当前菜单项的个数。
     * @return int 当前菜单项的个数。
     */
    public int itemCount() {
        return this.items.size();
    }
    /**
     * 清除所有的菜单。
     */
    public void removeAll() {
        this.items.removeAllElements();
        this.selectIndex = -1;
    }
    /**
     * 获得选中的序号。
     * @return int 选中的序号。
     */
    public int getSelectIndex() {
        return this.selectIndex;
    }
    /**
     * 指定选中的序号。
     * @param index int 选中的序号。
     */
    public void setSelectIndex(int index) {
        if (index >= 0 && index < this.items.size()) {
            this.selectIndex = index;
        }
    }
    /**
     * 获得选中的菜单文字。
     * @return String 选中的菜单文字。
     */
    public String getSelectedText() {
        if (this.selectIndex >= 0 && this.selectIndex < this.items.size()) {
            MenuItem mi = (MenuItem)this.items.elementAt(this.selectIndex);
            return mi.getText();
        } else {
            return null;
        }
    }
    /**
     * 菜单选中向上。
     */
    public void moveUp() {
        if (this.items.size() > 0) {
            this.selectIndex--;
            if (this.selectIndex < 0) {
                this.selectIndex += this.items.size();
            }
        }
    }
    /**
     * 菜单选中向下。
     */
    public void moveDown() {
        if (this.items.size() > 0) {
            this.selectIndex++;
            if (this.selectIndex >= this.items.size()) {
                this.selectIndex -= this.items.size();
            }
        }
    }
    /**
     * 获得当前菜单的最长菜单宽度。
     * @return int 最长的菜单宽度。
     */
    public int getMaxTextWidth() {
        return this.maxTextWidth;
    }
    /**
     * 计算当前菜单的宽度和高度。
     */
    private void calculateWidth() {
        int maxWidth = defaultMenuWidth;
        boolean hasNext = false;
        for (int i = 0; i < this.items.size(); i++) {
            MenuItem mi = (MenuItem)this.items.elementAt(i);
            if (mi.getSubmenu().items.size() > 0) {
                hasNext = true;
            }
            int w = Env.instance.defaultFont.stringWidth("1." + mi.getText());
            if (maxWidth < w) {
                maxWidth = w;
            }
        }
        this.maxTextWidth = maxWidth;
        if (hasNext) {
            this.r.width = this.maxTextWidth + Menu.moreIconWidth;
        } else {
            this.r.width = this.maxTextWidth;
        }
        this.r.height = Env.instance.defaultFontHeight * this.items.size();
    }
}
